//////////////////////////////////////////////////////////////////////////////////
//
// ActionScript 3.0 Common Library (MIT License)
// Copyright (c) 2009 AS3CommonCode | Tony Birleffi | http://www.mosaiceye.com
// 
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////////

package org.as3commoncode.net.loader 
{
	import flash.errors.IllegalOperationError;    
	import flash.events.Event;
    import flash.events.HTTPStatusEvent;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.URLLoader;
    import flash.net.URLRequest;

	import org.as3commoncode.net.loader.AbstractLoader;
	import org.as3commoncode.events.XMLLoaderEvent;	/**
	 * Loads in an xml file to an object.
	 * 
	 * @example
	 * <listing>
	 * var xmlLoader:XMLLoader = new XMLLoader("xml/config.xml");
	 * xmlLoader.addEventListener(XMLLoaderEvent.COMPLETE, onXMLComplete);
	 * xmlLoader.load();
	 * </listing>
	 * 
	 * @see org.as3commoncode.net.loader.AbstractLoader;
	 * @see org.as3commoncode.event.XMLLoaderEvent;
	 * 
	 * @author Tony Birleffi
	 */
    public class XMLLoader extends AbstractLoader 
	{
		/** Instance of the url loader class. */
        private var loader:URLLoader;
        
        /** Reference to the xml object loaded. */
		private var xml:XML;

		/**
         * Handles the initial setup.
         * 
		 * @param url		string path to the media file.
         */
        public function XMLLoader(url:String = null) 
		{
			// Call the super.
            super(new URLRequest(url));
            
            // Make an instance of the xml class.
            this.xml = new XML();
            
			// Make an instance of the loader class.
            this.loader = new URLLoader();
		}

		/**
         * Loads an XML file from the specified url, if you specified it 
		 * already in the constructor you can omit it.
		 * 
		 * @param urlRequest		an url request.
         */
        public override function load(urlRequest:URLRequest = null):void 
		{
			// You can also setup the URL request here as well.
            if(urlRequest != null) this.request = urlRequest;

			// Add the listeners.
            this.loader.addEventListener(Event.COMPLETE, xmlLoaded);
            this.loader.addEventListener(Event.OPEN, start);
            this.loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, delegate);
            this.loader.addEventListener(ProgressEvent.PROGRESS, delegate);
            this.loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, delegate);
            this.loader.addEventListener(IOErrorEvent.IO_ERROR, delegate);
			
			// Start the load.
            this.loader.load(request);
        }

        /**
         * Stops the download of the file.
         */
        public override function stop():void 
		{
			// If the load is running, close the load.
            if(running)
			{
				try { 
					this.loader.close();
				} catch(e:Error) {
					throw new IllegalOperationError("The loader never closed.");
				}
            }
			
			// Stop the load.
            running = false;
        }
        
		/**
         * Handles the xml loaded event.
         * 
		 * @param event		the event object.
         */
		private function xmlLoaded(event:Event):void
		{
			// Define the xml.
			this.xml = XML(this.loader.data);
			
			// Set the running.
			running = false;
			
			// Dispatch an event.
			dispatchEvent(new XMLLoaderEvent(XMLLoaderEvent.COMPLETE, this.xml));
		}
		
		/**
         * Simply delegates the event.
         * 
		 * @param event		the event object.
         */
        private function delegate(event:Event):void 
		{
            dispatchEvent(event);
        }
        
        /**
         * Returns the xml loaded in.
         * 
         * @return	XML.
         */
		public function get result():XML
		{
			return this.xml;
		}
    }
}